home *** CD-ROM | disk | FTP | other *** search
- /*
- File: Clipboard.c
-
- Contains: Clipboard support for simple text application.
-
- Version: SimpleText 1.4 or later
-
- ** Copyright 1993-1996 Apple Computer. All rights reserved.
- **
- ** You may incorporate this sample code into your applications without
- ** restriction, though the sample code has been provided "AS IS" and the
- ** responsibility for its operation is 100% yours. However, what you are
- ** not permitted to do is to redistribute the source as "DSC Sample Code"
- ** after having made changes. If you're going to re-distribute the source,
- ** we require that you make it clear in the source that the code was
- ** descended from Apple Sample Code, but that you've made changes.
-
- */
-
- #include "MacIncludes.h"
-
- #include "Clipboard.h"
-
-
- // --------------------------------------------------------------------------------------------------------------
- // GLOBALS FOR THIS FILE ONLY
- // --------------------------------------------------------------------------------------------------------------
- static Handle gScrapHandle;
- static long gCurrentOffset;
- static QDProcsPtr gSavedProcs;
- static QDProcs gMyProcs;
- static CQDProcs gMyColorProcs;
-
- // --------------------------------------------------------------------------------------------------------------
- // INTERNAL ROUTINES
- // --------------------------------------------------------------------------------------------------------------
- static pascal void GetPICTData(Ptr dataPtr, short byteCount)
- /*
- replacement for the QuickDraw bottleneck routine
- */
- {
- long longCount = byteCount;
-
- BlockMoveData((*gScrapHandle)+gCurrentOffset, dataPtr, longCount);
- gCurrentOffset += longCount;
-
- } // GetPICTData
-
- #if GENERATINGCFM
- static RoutineDescriptor gGetPICTDataRD = BUILD_ROUTINE_DESCRIPTOR(uppQDGetPicProcInfo, GetPICTData);
- static QDGetPicUPP gGetPICTData = &gGetPICTDataRD;
- #else
- static QDGetPicUPP gGetPICTData = NewQDGetPicProc(GetPICTData);
- #endif
-
- // --------------------------------------------------------------------------------------------------------------
-
- static OSErr DrawPictureFromHandleAndOffset(
- Rect * pWhereToDraw, // draw picture at this location
- Handle sourceHandle, // handle containing data
- long sourceOffset) // offset within handle to start at
- {
- OSErr anErr;
- Rect whereToDraw = *pWhereToDraw;
- PicHandle tempPict = (PicHandle) NewHandle(sizeof(Picture));
-
- anErr = MemError();
- nrequire(anErr, FailedNewHandle);
-
- // calculate the rectangle in which to draw, save the picture header into
- // our handle
- {
- PicPtr pPicture;
-
- pPicture = (PicPtr)((*sourceHandle) + sourceOffset);
- whereToDraw.right = whereToDraw.left + pPicture->picFrame.right - pPicture->picFrame.left;
- whereToDraw.bottom = whereToDraw.top + pPicture->picFrame.bottom - pPicture->picFrame.top;
- BlockMoveData((Ptr)pPicture, (Ptr)*tempPict, sizeof(Picture));
- }
-
- // store into globals for our GetPicProc in preparation for the draw
- gScrapHandle = sourceHandle;
- gCurrentOffset = sourceOffset + sizeof(Picture);
-
- // install our GetPic proc
- if (gMachineInfo.theEnvirons.hasColorQD)
- SetStdCProcs(&gMyColorProcs);
- else
- SetStdProcs(&gMyProcs);
- gMyProcs.getPicProc = gGetPICTData;
- gMyColorProcs.getPicProc = gGetPICTData;
- gSavedProcs = (*qd.thePort).grafProcs;
- if (gMachineInfo.theEnvirons.hasColorQD)
- (*qd.thePort).grafProcs = (QDProcsPtr)&gMyColorProcs;
- else
- (*qd.thePort).grafProcs = &gMyProcs;
-
- // Draw the picture
- DrawPicture(tempPict, &whereToDraw);
-
- // remove our GetPic proc
- (*qd.thePort).grafProcs = gSavedProcs;
-
- DisposeHandle((Handle)tempPict);
-
- // FALL THROUGH EXCEPTION HANDLING
- FailedNewHandle:
- return anErr;
-
- } // DrawPictureFromHandleAndOffset
-
- // --------------------------------------------------------------------------------------------------------------
- // OOP INTERFACE ROUTINES
- // --------------------------------------------------------------------------------------------------------------
- static OSErr ClipboardUpdateWindow(WindowRef pWindow, WindowDataPtr pData)
- {
- #pragma unused (pData)
-
- OSErr anErr;
- FontInfo theInfo;
- long scrapResult;
- long offset;
- ResType validScrapType = '????';
- Rect topAreaRect;
- RgnHandle oldClip = NewRgn();
-
- // clear out any data that was there before
- GetClip(oldClip);
- EraseRect(&GetWindowPort(pWindow)->portRect);
-
- // get that scrap!
- anErr = LoadScrap();
- nrequire(anErr, LoadScrap);
-
- // figure out the scrap type and offset
- {
- short i = 0;
- ResType scrapTypes[] = {'TEXT', 'PICT', '????'};
-
- while (scrapTypes[i] != '????')
- {
- scrapResult = GetScrap(nil, scrapTypes[i], &offset);
- if (scrapResult > 0)
- {
- validScrapType = scrapTypes[i];
- break;
- }
- ++i;
- }
- }
-
- // setup for the drawing
- TextFont(applFont);
- TextSize(9);
- GetFontInfo(&theInfo);
-
- // caclulate our area at the top to say what type of contents the scrap is
- topAreaRect = GetWindowPort(pWindow)->portRect;
- topAreaRect.bottom = topAreaRect.top + theInfo.ascent + theInfo.descent + theInfo.leading * 2 + 2;
-
- // draw two lines under the area to separate it from the rest of the window
- MoveTo(topAreaRect.left, topAreaRect.bottom - 2);
- Line(topAreaRect.right - topAreaRect.left, 0);
- Move(0, 2);
- Line(-(topAreaRect.right - topAreaRect.left), 0);
-
- // draw a string describing the contents
- {
- Str255 theString;
-
- switch (validScrapType)
- {
- case 'PICT':
- GetIndString(theString, kClipboardStrings, iClipboardPICT);
- break;
-
- case 'TEXT':
- GetIndString(theString, kClipboardStrings, iClipboardText);
- break;
-
- default:
- if (InfoScrap()->scrapCount == 0)
- GetIndString(theString, kClipboardStrings, iClipboardNone);
- else
- GetIndString(theString, kClipboardStrings, iClipboardUnknown);
- break;
- }
-
- MoveTo(topAreaRect.left + 4, topAreaRect.bottom - 4);
- DrawString(theString);
- }
-
- // calculate the part *not* in our top area
- topAreaRect.top = topAreaRect.bottom+1;
- topAreaRect.bottom = GetWindowPort(pWindow)->portRect.bottom;
-
- // remember the scrap count -- if it changes, we do an update!
- ((ClipboardDataPtr)pData)->scrapCount = InfoScrap()->scrapCount;
-
- // now, draw the contents, if we have a legal type to use
- {
- Rect clipArea = topAreaRect;
- Handle scrapHandle = InfoScrap()->scrapHandle;
-
- clipArea.right -= 15;
- clipArea.bottom -= 15;
- ClipRect(&clipArea);
- switch (validScrapType)
- {
- case 'PICT':
- DrawPictureFromHandleAndOffset(&clipArea,
- scrapHandle, offset);
- break;
-
- case 'TEXT':
- {
- char oldState;
-
- oldState = HGetState(scrapHandle);
- HLock(scrapHandle);
- clipArea.right -= 15;
- clipArea.bottom -= 15;
- TETextBox(*scrapHandle+offset, scrapResult, &clipArea, teJustLeft);
- }
- break;
- }
- }
-
- // finally draw the grow icon, but omit our top area rect from the drawing
- ClipRect(&topAreaRect);
- DrawGrowIcon(pWindow);
-
- SetClip(oldClip);
- DisposeRgn(oldClip);
-
- UnloadScrap();
-
- // FALL THROUGH EXCEPTION HANDLING
- LoadScrap:
- return anErr;
-
- } // ClipboardUpdateWindow
-
-
- // --------------------------------------------------------------------------------------------------------------
-
- static Boolean ClipboardFilterEvent(WindowRef pWindow, WindowDataPtr pData, EventRecord *pEvent)
- {
-
- // Force an update on scrap changes during activate/deactivate.
-
- switch (pEvent->what)
- {
- case nullEvent:
- case activateEvt:
- if (LoadScrap() == noErr)
- {
- PScrapStuff pScrap = InfoScrap();
-
- if (pScrap->scrapCount != ((ClipboardDataPtr)pData)->scrapCount)
- {
- GrafPtr pPort = (GrafPtr)GetWindowPort(pWindow);
-
- SetPort(pPort);
- InvalRect(&pPort->portRect);
- }
- }
- break;
-
- // Follow the HI guidelines and hide the clipboard when we are suspended.
-
- case osEvt:
- if (((pEvent->message >> 24) & 0x0FF) == suspendResumeMessage)
- {
- if((pEvent->message & resumeFlag)==0) // suspending
- {
- HideWindow(pWindow);
- pWindow = FrontWindow();
- if (pWindow)
- HiliteWindow(pWindow, false);
- }
- else // resuming
- ShowWindow(pWindow);
- }
- break;
-
- } // switch(what)
-
- return false;
-
- } // ClipboardFilterEvent
-
-
- // --------------------------------------------------------------------------------------------------------------
-
- static OSErr ClipboardKeyEvent(WindowRef pWindow, WindowDataPtr pData, EventRecord *pEvent, Boolean isMotionKey)
- {
- #pragma unused(pWindow, pData, pEvent, isMotionKey)
-
- return noErr;
-
- } // ClipboardKeyEvent
-
-
- // --------------------------------------------------------------------------------------------------------------
-
- static OSErr ClipboardGetBalloon(WindowRef pWindow, WindowDataPtr pData,
- Point *localMouse, short * returnedBalloonIndex, Rect *returnedRectangle)
- {
- #pragma unused (pWindow, pData, localMouse, returnedRectangle)
-
- *returnedBalloonIndex = iNoBalloon;
-
- return noErr;
-
- } // ClipboardGetBalloon
-
- // --------------------------------------------------------------------------------------------------------------
-
- static OSErr ClipboardGetDocumentRect(WindowRef pWindow, WindowDataPtr pData,
- LongRect * documentRectangle, Boolean forGrow)
- {
- #pragma unused (pWindow, pData, forGrow)
-
- Rect maxSize = (**GetGrayRgn()).rgnBBox;
-
- RectToLongRect(&maxSize, documentRectangle);
-
- return noErr;
-
- } // ClipboardGetDocumentRect
-
-
- // --------------------------------------------------------------------------------------------------------------
-
- static OSErr ClipboardCloseWindow(WindowRef pWindow, void* refCon)
- {
- #pragma unused(pWindow,refCon)
-
- ChangeCommandName(cShowClipboard, kClipboardStrings, iClipboardShow);
- UnloadScrap();
-
- return noErr;
-
- } // ClipboardCloseWindow
-
-
- // --------------------------------------------------------------------------------------------------------------
-
- static OSErr ClipboardMakeWindow(WindowRef pWindow, WindowDataPtr pData)
- {
- #pragma unused (pWindow)
-
- pData->hasGrow = true;
- pData->pFilterEvent = (FilterEventProc) ClipboardFilterEvent;
- pData->pKeyEvent = (KeyEventProc) ClipboardKeyEvent;
- pData->pGetBalloon = (GetBalloonProc) ClipboardGetBalloon;
- pData->pUpdateWindow = (UpdateWindowProc) ClipboardUpdateWindow;
- pData->pGetDocumentRect = (GetDocumentRectProc) ClipboardGetDocumentRect;
- pData->pCloseWindow = (CloseWindowProc) ClipboardCloseWindow;
-
- pData->contentRect.right = pData->contentRect.left +
- qd.screenBits.bounds.right - qd.screenBits.bounds.left - 96;
- pData->contentRect.bottom = pData->contentRect.top + 150;
- MoveWindow(pWindow,
- qd.screenBits.bounds.left + 4,
- qd.screenBits.bounds.bottom - 154, false);
-
- ChangeCommandName(cShowClipboard, kClipboardStrings, iClipboardHide);
-
- return noErr;
-
- } // ClipboardMakeWindow
-
-
- // --------------------------------------------------------------------------------------------------------------
-
- OSErr ClipboardPreflightWindow(PreflightPtr pPreflightData)
- {
- pPreflightData->resourceID = kClipboardWindowID;
- pPreflightData->continueWithOpen = true;
- pPreflightData->makeProcPtr = ClipboardMakeWindow;
- pPreflightData->storageSize = sizeof(ClipboardDataRecord);
-
- return noErr;
-
- } // ClipboardPreflightWindow
-
- // --------------------------------------------------------------------------------------------------------------
-
- void ClipboardGetFileTypes(OSType * pFileTypes, OSType * pDocumentTypes, short * numTypes)
- {
- #pragma unused (pFileTypes, pDocumentTypes, numTypes)
-
- } // ClipboardGetFileTypes
-